package com.alks.function.service.impl.pcfactorywork;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.UserInfoUtil;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.entity.data.entity.PcDhLotHead;
import com.alks.entity.data.entity.PcLotPriceOther;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.pcfactorywork.OutUnitPriceDto;
import com.alks.function.data.dto.pcfactorywork.PcDhPriceDto;
import com.alks.function.data.request.factorywork.PcDhLotCFMRequest;
import com.alks.function.data.request.factorywork.PcDhLotRequest;
import com.alks.function.data.request.factorywork.PcLotPriceOtherAddRequest;
import com.alks.function.data.request.factorywork.PcLotPriceOtherUpdateRequest;
import com.alks.function.data.vo.pcfactoryWork.OutUnitPriceVo;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.pcfactorywork.PcDhLotHeadMapper;
import com.alks.function.mapper.pcfactorywork.PcLotPriceOtherMapper;
import com.alks.function.service.pcfactorywork.IPcDhLotHeadService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.ResultCodeEnum.LOGIN_CONFIG_IS_NULL;

/**
 * <p>
 * 指令资料 服务实现类
 * </p>
 *
 * @author ms
 * @since 2023-07-21
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PcDhLotHeadServiceImpl extends ServiceImpl<PcDhLotHeadMapper, PcDhLotHead> implements IPcDhLotHeadService {
    private final PcDhLotHeadMapper lMapper;
    private final PcLotPriceOtherMapper priceMapper;
    private final PcLotHeadMapper headMapper;

    @Override
    @AutoPageAop
    public Map<String, Object> listPcDhLot(PcDhLotRequest request) {
        /*分页数据查询*/
        List<OutUnitPriceVo> headList = headMapper.listPcDhLot(request, UserIdThread.get().getCompanyId());
        /*处理制程*/
        headList.forEach(a -> {
            /*制程要么是全套，要么是其他的组合起来*/
            a.setCostPrice(a.getCostPrice() == null ? BigDecimal.ZERO : a.getCostPrice());
            a.setCraftPrice(a.getCraftPrice() == null ? BigDecimal.ZERO : a.getCraftPrice());
            a.setStitchPrice(a.getStitchPrice() == null ? BigDecimal.ZERO : a.getStitchPrice());
            if (a.getProcessAll() == null) {
                StringJoiner joiner = new StringJoiner("");
                joiner.add(a.getProcessCut01() == null ? "" : a.getProcessCut01())
                        .add(a.getProcessCut02() == null ? "" : a.getProcessCut02())
                        .add(a.getProcessCut03() == null ? "" : a.getProcessCut03())
                        .add(a.getProcessStitch() == null ? "" : a.getProcessStitch())
                        .add(a.getProcessLast() == null ? "" : a.getProcessLast())
                        .add(a.getOutFlag() == null ? "" : a.getOutFlag());
                a.setProcessAll(joiner.toString());
            }
            a.setProcess(a.getProcessAll());
            a.setCostPrice(a.getCraftPrice().add(a.getCostPrice().add(a.getStitchPrice())));
        });
        List<OutUnitPriceDto> dtos = BeanUtil.copyList(headList, OutUnitPriceDto.class);
        /*获取总额*/
        Map<String,Object> map = headMapper.outUnionPriceSum(request, UserIdThread.get().getCompanyId());
        map = map==null?new HashMap<>():map;
        /*封装*/
        if (request.getPageNum() != -1) {
            Page<OutUnitPriceVo> page = (Page<OutUnitPriceVo>) headList;
            map.put("total", page.getTotal());
        }
        map.put("dtos", dtos);
        return map;
    }


    @Override
    public ResponseInfo<Map<String, Object>> listPcDhPrice(String lotNo) {
        /*数据查询*/
        LambdaQueryWrapper<PcLotPriceOther> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PcLotPriceOther::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(PcLotPriceOther::getLotNo, lotNo)
                .ne(PcLotPriceOther::getProcess, "外接单价");        //外界单价是主表部分数据
        List<PcLotPriceOther> priceList = priceMapper.listPcDhPrice(lotNo);
        /*提取拷贝*/
        List<PcDhPriceDto> dtos = BeanUtil.copyList(priceList, PcDhPriceDto.class);
        /*封装求和*/
        BigDecimal priceSum = dtos.stream().map(PcDhPriceDto::getPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        Map<String, Object> map = new HashMap<>();
        map.put("dtos", dtos);
        map.put("priceSum", priceSum);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo auditDhDetail(PcDhLotCFMRequest request) {
        /*判空*/
        if (request.getLotNoList().isEmpty())
            return ResponseInfo.error("请选择需要检核的数据", LOGIN_CONFIG_IS_NULL.getCode());
        if (request.getCfmFlag().equals("N")) {
            /*判断是否已结单*/
            LambdaQueryWrapper<PcLotPriceOther> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(PcLotPriceOther::getLotNo)
                    .isNotNull(PcLotPriceOther::getFinanceYymm)
                    .in(PcLotPriceOther::getLotNo, request.getLotNoList())
                    .eq(PcLotPriceOther::getCompanyId, UserIdThread.get().getCompanyId())
                    .eq(PcLotPriceOther::getProcess, "外接单价");
            List<String> lotNos = priceMapper.selectList(queryWrapper).stream().map(PcLotPriceOther::getLotNo).collect(Collectors.toList());
            if (!ArrayUtils.isEmpyt(lotNos)) {
                log.warn("接口：auditDhDetail 尝试取消审核已结算数据{}\n参照表：PC_LOT_PRICE_OTHER", lotNos);
                return ResponseInfo.error("包括" + lotNos.get(0) + "在内" + lotNos.size() + "条数据已结算", LOGIN_CONFIG_IS_NULL.getCode());
            }
        } else {
            /*判断是否存在无明细数据*/
            LambdaQueryWrapper<PcLotPriceOther> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(PcLotPriceOther::getLotNo)
                    .in(PcLotPriceOther::getLotNo, request.getLotNoList())
                    .eq(PcLotPriceOther::getCompanyId, UserIdThread.get().getCompanyId())
                    .ne(PcLotPriceOther::getProcess, "外接单价");
            Set<String> lotNoSet = priceMapper.selectList(queryWrapper).stream().map(PcLotPriceOther::getLotNo).collect(Collectors.toSet());
            List<String> miss = ArrayUtils.findMiss(lotNoSet, request.getLotNoList());
            if (!ArrayUtils.isEmpyt(miss)) {
                log.warn("接口：auditDhDetail 尝试审核无明细数据{}\n参照表：PC_LOT_PRICE_OTHER", miss);
                return ResponseInfo.error("包括" + miss.get(0) + "在内" + miss.size() + "条数据缺少单价明细", LOGIN_CONFIG_IS_NULL.getCode());
            }
        }
        /*更新数据*/
        LambdaUpdateWrapper<PcLotPriceOther> update = new LambdaUpdateWrapper<PcLotPriceOther>()
                .in(PcLotPriceOther::getLotNo, request.getLotNoList())
                .eq(PcLotPriceOther::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(PcLotPriceOther::getProcess, "外接单价")
                .set(request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmFlag, null)
                .set(request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmDate, null)
                .set(request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmUser, null)
                .set(request.getCfmFlag() == null || !request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmFlag, "Y")
                .set(request.getCfmFlag() == null || !request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmDate, LocalDate.now())
                .set(request.getCfmFlag() == null || !request.getCfmFlag().equals("N"), PcLotPriceOther::getCfmUser, UserIdThread.get().getUserId());
        priceMapper.update(null, update);
        return ResponseInfo.ok();
    }

    /**
     * 插入外接单价
     *
     * @param request
     * @return
     */
    @Override
    public ResponseInfo InsertExternalInitPrice(PcLotPriceOtherUpdateRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("请选择指令!");
        }
        if (ObjectUtils.isEmpty(request.getPrice())) {
            return ResponseInfo.error("请输入单价!");
        }
        LambdaQueryWrapper<PcLotPriceOther> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotPriceOther::getLotNo, request.getLotNo()).eq(PcLotPriceOther::getProcess, "外接单价");
        PcLotPriceOther pcLotPriceOther = priceMapper.selectOne(wrapper);
        String userName = UserInfoUtil.getUserInfo().getUserName();
        if (ObjectUtils.isEmpty(pcLotPriceOther)) {
            pcLotPriceOther = new PcLotPriceOther();
            pcLotPriceOther.setLotNo(request.getLotNo());
            pcLotPriceOther.setSlipDate(LocalDateTime.now());
            pcLotPriceOther.setProcess("外接单价");
            pcLotPriceOther.setPrice(request.getPrice());
            pcLotPriceOther.setSysUser(userName);
            pcLotPriceOther.setSysDate(LocalDateTime.now());
            pcLotPriceOther.setCompanyId(UserIdThread.get().getCompanyId());
            priceMapper.insert(pcLotPriceOther);
        }
        priceMapper.updatePcLotPriceOtherPrice(request.getLotNo(), request.getPrice(), userName, LocalDateTime.now(), LocalDateTime.now());
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 预算项目新增
     *
     * @param request
     * @return
     */
    @Override
    public ResponseInfo AddBudgetItem(PcLotPriceOtherAddRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getProcess())) {
            return ResponseInfo.error("预算项目不能为空!");
        }
        if (request.getProcess().equals("外接单价")) {
            return ResponseInfo.error("该指令下已存在该预算项目!");
        }
        LambdaQueryWrapper<PcLotPriceOther> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PcLotPriceOther::getLotNo, request.getLotNo()).eq(PcLotPriceOther::getProcess, request.getProcess());
        PcLotPriceOther pcLotPriceOther = priceMapper.selectOne(wrapper);
        if (!ObjectUtils.isEmpty(pcLotPriceOther)) {
            return ResponseInfo.error("该指令下已存在该预算项目!");
        }
        PcLotPriceOther entity = new PcLotPriceOther();
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        entity.setCompanyId(userInfo.getCompanyId());
        entity.setSysUser(userInfo.getUserName());
        entity.setSysDate(LocalDateTime.now());
        entity.setSlipDate(LocalDateTime.now());
        entity.setLotNo(request.getLotNo());
        entity.setProcess(request.getProcess());
        entity.setPrice(request.getPrice());
        entity.setRemark(request.getRemark());
        priceMapper.insert(entity);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 修改预算项目
     *
     * @param request
     * @return
     */
    @Override
    public ResponseInfo ModifyBudgetItems(PcLotPriceOtherAddRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getProcess())) {
            return ResponseInfo.error("预算项目不能为空!");
        }
        if (request.getProcess().equals("外接单价")) {
            return ResponseInfo.error("该指令下已存在该预算项目!");
        }
        LambdaUpdateWrapper<PcLotPriceOther> update = new LambdaUpdateWrapper<PcLotPriceOther>()
                .eq(PcLotPriceOther::getLotNo, request.getLotNo())
                .eq(PcLotPriceOther::getProcess, request.getProcess())
                .set(PcLotPriceOther::getPrice, request.getPrice())
                .set(PcLotPriceOther::getRemark, request.getRemark())
                .set(PcLotPriceOther::getSysUser, UserInfoUtil.getUserInfo().getUserName())
                .set(PcLotPriceOther::getSysDate, LocalDateTime.now());
        priceMapper.update(null, update);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 删除预算项目
     *
     * @param request
     * @return
     */
    @Override
    public ResponseInfo DeleteBudgetItems(PcLotPriceOtherAddRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getProcess())) {
            return ResponseInfo.error("预算项目不能为空!");
        }
        LambdaQueryWrapper<PcLotPriceOther> wrapper = new LambdaQueryWrapper<PcLotPriceOther>()
                .eq(PcLotPriceOther::getLotNo, request.getLotNo())
                .eq(PcLotPriceOther::getProcess, request.getProcess());
        priceMapper.delete(wrapper);
        return ResponseInfo.ok("操作成功!");
    }
}
